package com.orangelife.service.base.dict;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * <p>
 * 字典对象行为接口
 * </p>
 * <p>
 * 该接口要求实现必须是<b>线程安全</b>的。
 * </p>
 * 
 * <p>
 * 对于一般的字典来说，基本行为是先构造再使用。 且在构造完成后，应该不再暴露增加和修改字典模型的操作。
 * 
 * </p>
 * <p>
 * 最基本的要求，是在构造完成后，不允许进行修改或者删除。 若真有该行为需求，建议在最终实现类进行追加，而不该在模版中进行追加。
 * 因为这可能会影响到具体字典对象的线程安全特性。
 * </p>
 * 
 * @author lance
 * 
 * @param <T>
 *            字典集的查询键类型
 * @param <K>
 *            字典集的查询返回对象类型
 */
public interface Dictionary<K, T> extends Cloneable {

	/**
	 * 返回所有的键值
	 * <p>
	 * 
	 * @return 所有键值数组
	 */
	public Set<K> keys();

	/**
	 * 根据比较器返回键值序列。
	 * <p>
	 * 若比较器为空，则要求所有的键值必须实现<code>Comparable</code>接口
	 * <p>
	 * 若不遵从该协定，则可能因为无法进行强制转换而抛出<code>ClassCastException</code>异常
	 * 
	 * @param comparator
	 * @return
	 */
	public List<K> keysList(Comparator<K> comparator);

	/**
	 * <p>
	 * 根据键值返回被查询对象
	 * </p>
	 * <p>
	 * 必须确保构造时的键值对中是否存在<tt>key == null</tt>的情况,字典对象中不应该包含该情况。
	 * </p>
	 * <p>
	 * 在获取对象操作时，当<tt>key == null</tt>，将确保统一返回为null
	 * </p>
	 * 
	 * @param key
	 * @return 返回被查询对象，查询不存在则返回<tt>null</tt>
	 */
	public T get(K key);

	/**
	 * <p>
	 * 返回条目总数
	 * </p>
	 * 
	 * @return
	 */
	public int size();

	/**
	 * <p>
	 * 返回字典是否为空
	 * </p>
	 * 
	 * @return
	 */
	public boolean isEmpty();

	/**
	 * <p>
	 * 获得一本字典的克隆
	 * </p>
	 * <p>
	 * 如下行为必须确保：
	 * </p>
	 * 
	 * <pre>
	 * ...defined Dictionary<K, T> simDictDemo
	 * 
	 * Dictionary<K, T> clone = (Dictionary<K, T>) simDictDemo.clone();
	 * assertEquals(false, clone == simDictDemo);
	 * 
	 * ...test clone behavior the same as simDictDemo
	 * 
	 * SimpleDictionary<K, T> simpleClone = (SimpleDictionary<K, T>) clone;
	 * simpleClone.addDictEntry("test", "test");
	 * 
	 * ...the behavior of simDictDemo is not change!
	 * 
	 * </pre>
	 * 
	 * 
	 * 
	 * @return
	 */
	public Dictionary<K, T> clone();

	/**
	 * 将字典的条目转化成键值对，装入容器<code>container</code>
	 * <p>
	 * 
	 * @param conainer
	 */
	public void toMaps(Map<K, T> container);

}
